package com.kinsin.kinsinutil

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.annotation.RequiresPermission
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData

@SuppressLint("MissingPermission")
class NetworkStateMonitor private constructor(context: Context) {

    private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE)
            as ConnectivityManager

    // 状态防抖处理
    private val debounceHandler = Handler(Looper.getMainLooper())
    private var currentState: NetworkState = NetworkState.Disconnected

    private val _networkState = MutableLiveData<NetworkState>()
    val networkState: LiveData<NetworkState> get() = _networkState

    private val networkCallback = object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) = triggerStateUpdate()
        override fun onLost(network: Network) = triggerStateUpdate()
        override fun onCapabilitiesChanged(network: Network, capabilities: NetworkCapabilities) = triggerStateUpdate()
    }

    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    private constructor(context: Context, init: Boolean) : this(context) {
        initNetworkCallback(context)
    }

    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    private fun initNetworkCallback(context: Context) {
        val networkRequest = NetworkRequest.Builder()
            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            .build()
        connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
        triggerStateUpdate()
    }

    // 防抖处理（300ms）
    private fun triggerStateUpdate() {
        debounceHandler.removeCallbacksAndMessages(null)
        debounceHandler.postDelayed(::updateNetworkState, 300)
    }

    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    private fun updateNetworkState() {
        val activeNetwork = connectivityManager.activeNetwork
        val capabilities = activeNetwork?.let { connectivityManager.getNetworkCapabilities(it) }

        val newState = when {
            capabilities == null -> NetworkState.Disconnected
            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ->
                NetworkState.ConnectedWithType(ConnectionType.WIFI)
            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ->
                NetworkState.ConnectedWithType(ConnectionType.CELLULAR)
            capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true ->
                NetworkState.Connected
            else -> NetworkState.Disconnected
        }

        if (newState != currentState) {
            currentState = newState
            _networkState.postValue(newState)
        }
    }

    companion object {
        @Volatile
        private var instance: NetworkStateMonitor? = null

        @JvmStatic
        @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
        fun getInstance(context: Context, isDebug: Boolean = false): NetworkStateMonitor {
            return instance ?: synchronized(this) {
                instance ?: NetworkStateMonitor(context, true).also {
                    if (isDebug) checkPermission(context)
                    instance = it
                }
            }
        }

        @SuppressLint("LogNotTimber")
        private fun checkPermission(context: Context) {
            try {
                val info = context.packageManager.getPackageInfo(
                    context.packageName,
                    PackageManager.GET_PERMISSIONS
                )
                if (info.requestedPermissions?.contains(Manifest.permission.ACCESS_NETWORK_STATE) == false) {
                    Log.e("NetworkMonitor", """
                        Missing required permission in AndroidManifest.xml:
                        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
                        """.trimIndent()
                    )
                }
            } catch (e: Exception) {
                Log.e("NetworkMonitor", "Permission check failed: ${e.message}")
            }
        }
    }
}

sealed class NetworkState {
    object Connected : NetworkState()
    object Disconnected : NetworkState()
    data class ConnectedWithType(val type: ConnectionType) : NetworkState()
}

/**
 * 网络连接类型枚举
 *
 * 该枚举用于标识设备当前的网络连接类型，包含以下可能值：
 *
 * - [WIFI] 表示通过Wi-Fi无线网络连接
 * - [CELLULAR] 表示通过移动数据网络连接（包括2G/3G/4G/5G等蜂窝网络）
 * - [UNKNOWN] 表示无法识别的网络类型（可能出现在新类型网络或特殊连接场景）
 *
 * 使用场景示例：
 * ```
 * when(connectionType) {
 *     ConnectionType.WIFI -> showWifiIndicator()
 *     ConnectionType.CELLULAR -> showMobileDataWarning()
 *     ConnectionType.UNKNOWN -> handleUnknownConnection()
 * }
 * ```
 *
 * @see NetworkState.ConnectedWithType 关联的网络状态封装类
 * @see NetworkCapabilities 底层网络能力检测来源
 */
enum class ConnectionType {
    WIFI, CELLULAR, UNKNOWN
}